#include "cmdworldboss.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "commmsg.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_WORLD_BOSS, CCmdWorldBoss);

int CCmdWorldBoss::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_WORLD_BOSS ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_WORLD_BOSS,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

	chSubCmd = stReq.sub_type();
    uiGID = stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    stAns.set_sub_type(chSubCmd);
    stAns.set_gid((int)uiGID);

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdWorldBoss::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_EX1_INFO(uiGID);

    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
	{
        CT_ERROR(("no base data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
	}
	CPlayerBaseInfo& stPlayerBase = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBase._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
	{
        CT_ERROR(("no detail data user(%u)", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
	}
	CPlayerDetailInfo& stPlayerDetail = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user detail ex1 info error, uid = %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1Info = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->FindPlayerCacheData(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no cache data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
	CPlayerCacheData& stPlayerCache = pstMainCtrl->m_stPlayerCacheDataHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
	CPlayerOnlineData& stPlayerOnline = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    stCmdData.Clear();
	switch (chSubCmd)
	{
	case CWorldBossMgr::CMD_WORLD_BOSS_SUB_BUFF:
        {
            iRet = pstMainCtrl->m_stWorldBossMgr.BuyMerlin(stPlayerBase,
                stPlayerCache, stAns);

            //新手目标
            if (RET_OK == iRet)
            {
                pstMainCtrl->m_stNewbieTaskMgr.Trigger(stPlayerDetailEx1Info._stNewbieTaskUserData, uiGID, NEWBIE_TASK_COND_13, 1);
            }
        }
		break;
	case CWorldBossMgr::CMD_WORLD_BOSS_SUB_REVIVE:
    	iRet = pstMainCtrl->m_stWorldBossMgr.DeadRevive(stPlayerBase,
            stPlayerCache, stAns);
		break;
	case CWorldBossMgr::CMD_WORLD_BOSS_SUB_BATTLE:
        {
    	    iRet = pstMainCtrl->m_stWorldBossMgr.WorldBossBattle(stPlayerBase,
                stPlayerDetail, stPlayerOnline, stPlayerCache, stReq, stAns,
                stCmdData);
            
            //触发任务
            CMainCtrl::m_pstMain->m_stDailyTaskMgr.TriggerTaskFinish(
                stPlayerOnline._stUserDailyTask, DAILY_TASK_ID_22);
        }
		break;
    case CWorldBossMgr::CMD_WORLD_BOSS_SUB_ATK_RANK:
        iRet = pstMainCtrl->m_stWorldBossMgr.GetWorldBossSceneInfo(
            stPlayerCache, stAns);
        return AnsClients(iRet);
	default:
		iRet = ERROR_MAIN_SUB_CMD;
		break;
	}

    if (iRet)
    {
        CT_TRACE(("user(gid=%u) deal world boss op(sub=%d) error(%d)",uiGID,chSubCmd,iRet));
        return AnsClients(iRet);
    }

	if (chSubCmd == CWorldBossMgr::CMD_WORLD_BOSS_SUB_BUFF ||
		chSubCmd == CWorldBossMgr::CMD_WORLD_BOSS_SUB_REVIVE ||
		chSubCmd == CWorldBossMgr::CMD_WORLD_BOSS_SUB_BATTLE)
	{
    	//保存数据 base info
    	CVarObjectKey stKey;
    	stKey.m_chDataType = DT_PLAYER_BASE_INFO;
    	stKey.m_u64ID = uiGID;
    	pstMainCtrl->UpdateData(stKey, stPlayerBase, VOP_UPDATE);

    	//保存数据 detail info
    	stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    	stKey.m_u64ID = uiGID;
    	pstMainCtrl->UpdateData(stKey, stPlayerDetail, VOP_UPDATE);
	}

    return AnsClients(RET_OK);
}

int CCmdWorldBoss::AnsClients(int iRet)
{
    pstMainCtrl->m_stEncodeBuf.Clear();

    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);

    if (pstMainCtrl->AnswerToClient(stEnpHead,pstMainCtrl->m_stEncodeBuf,true))
    {
        return Done(RET_SYS_ERROR);
    }

    //第二层触发逻辑在这里
    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex >= 0)
	{
	    CPlayerBaseInfo& stPlayerBase =
            pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
        if (stCmdData.GetFiftyKill())
        {
            pstMainCtrl->m_stWorldBossMgr.WorldBossNotifyTips(
                TIPS_WORLD_BOSS_FIFTY, stCmdData.GetFiftySilver(),
                stCmdData.GetFiftyRepu(), stPlayerBase);

            pstMainCtrl->FlushSendCache();
        }

        if (stCmdData.GetDeadKill())
        {
            pstMainCtrl->m_stWorldBossMgr.WorldBossNotifyTips(
                TIPS_WORLD_BOSS_KILL_BOSS, stCmdData.GetDeadSilver(),
                stCmdData.GetDeadRepu(), stPlayerBase);

            pstMainCtrl->FlushSendCache();
        }
	}
    else
    {
        CT_ERROR(("no base data user(%u)", uiGID));
    }

    if (stCmdData.GetActClose())
    {
        pstMainCtrl->m_stActMgr.SetActClose(ACT_ID_WORLD_BOSS);
        pstMainCtrl->FlushSendCache();
    }

    return Done(iRet);
}

